#include"webdownload.h"
#include<iostream>
#include<regex>
#include<atomic>
#include<mutex>
using namespace std;

WebDownload* WebDownload::m_instance;
atomic<WebDownload*> g_load;
mutex g_mutex;

WebDownload::WebDownload()
{
    curl_global_init(CURL_GLOBAL_ALL);
    m_curl=curl_easy_init();
}

WebDownload::~WebDownload()
{
    curl_easy_cleanup(m_curl);
}

WebDownload* WebDownload::GetInstance()
{
    m_instance=g_load.load(std::memory_order_relaxed);
    atomic_thread_fence(std::memory_order_acquire);
    if(m_instance==nullptr)
    {
        lock_guard<mutex> lock(g_mutex);
        if(m_instance==nullptr)
        {
            m_instance=new WebDownload();
            atomic_thread_fence(std::memory_order_release);
            g_load.store(m_instance,memory_order_relaxed);
        }
    }
    return m_instance;
}

bool WebDownload::GoDownload(const std::string& url,const std::string& outfilename)
{
    curl_easy_setopt(m_curl,CURLOPT_URL,url.c_str());
    FILE* out=fopen(outfilename.c_str(),"w");
    if(out==NULL)
    {
        return false;
    }
    curl_easy_setopt(m_curl,CURLOPT_WRITEDATA,out);
    curl_easy_setopt(m_curl,CURLOPT_WRITEFUNCTION,WebDownload::WriteFunc);
    curl_easy_perform(m_curl);

    printf("Done!\n");
    fclose(out);
    return true;
}

size_t WebDownload::WriteFunc(void* ptr,size_t size,size_t ncount,void* stream)
{
    int wsize=fwrite(ptr,size,ncount,(FILE*)stream);
    return wsize;
}

void WebDownload::Release()
{
    delete m_instance;
    m_instance=nullptr;
}
